package com.ccl.iot.publics;import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;

public class FileSystem {	
	public static boolean FolderExists(String aFolder, boolean aCreateWhenNotExist){
		if (aFolder != null){
			File tFile = new File(aFolder);
			
			if (tFile.exists()){
				return tFile.isDirectory();
			}else{
				if (aCreateWhenNotExist){
					if (aFolder.endsWith("/")){
						return tFile.mkdirs();
					}else{
						File tDir = new File(tFile.getParent());
						
						if (tDir != null){
							return tDir.mkdirs();				
						}
					}
				}		
			}
		}
		
		return false;
	}
	
	/*
	 * Judge file exists
	 * Parameter:
	 * 		aFileName - full file path
	 * Return:true - file exists;false - file not exists
	 */
	public static boolean FileExists(String aFileName, boolean aCreateWhenNotExist){
		if (aFileName != null){
			File tFile = new File(aFileName);
			if (tFile.exists()){
				return !tFile.isDirectory();
			}else{
				if (aCreateWhenNotExist){
					try {
						File tDir = new File(tFile.getParent());
						
						if (tDir != null){
							tDir.mkdirs();				
						}
						
						return tFile.createNewFile();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}else{
					return false;
				}
			}
		}
		return false;
	}
	
	public static String FixFolder(String aFolder){
		if (aFolder != null){
			if (aFolder.endsWith("/") == false){
				return aFolder + "/";
			}
		}
		
		return aFolder;
	}
	
	/*
	 * Get file folder path from file path
	 */
	public static String GetFileFolder(String aFilePath){
		int tPathLen = aFilePath.lastIndexOf("/");
		
		if (tPathLen > 0){
			return aFilePath.substring(0, tPathLen);
		}else{
			return aFilePath;
		}
	}
	
	/*
	 * Return the full path with an reference path
	 * Parameter:
	 * 		aSrcPath - source path
	 * 		aRefpath - reference path
	 * Return: final full path
	 */
	public static String FullPath(String aSrcPath, String aRefPath){
		if (aSrcPath != null && aRefPath != null){
			try{
				aSrcPath = aSrcPath.replaceAll("\\\\", "/");
				aRefPath = aRefPath.replaceAll("\\\\", "/");
				
				String tRefPath = GetFileFolder(aRefPath);
				
				String tFinalPath = null;
				if (aSrcPath.length() > 1){
					if (aSrcPath.startsWith("./")){
						tFinalPath = aSrcPath.substring(1);
					}else{
						if (aSrcPath.length() > 2){
							if (aSrcPath.startsWith("../")){
								tFinalPath = aSrcPath.substring(2);
								tRefPath = GetFileFolder(tRefPath);
							}
						}
					}
				}
			
				if (tFinalPath != null){
					return tRefPath.concat(tFinalPath);
				}
			}catch (Exception e){
				e.printStackTrace();
			}			
		}

	
		return aSrcPath;
	}
	
	public static String ShortPath(String aSrcPath, String aRefPath){
		if (aSrcPath != null && aRefPath != null){
			String tPath;
			
			if ((tPath = GetFileFolder(aRefPath)) != null){
				String tFinalPath = aSrcPath.replace(tPath, ".");
				
				if (tFinalPath.length() == aSrcPath.length()){
					if ((tPath = GetFileFolder(tPath.substring(0, tPath.length() - 1))) != null){
						return aSrcPath.replace(tPath, "..");
					}
				}else{
					return tFinalPath;
				}
			}
		}
		
		return aSrcPath;
	}
	
	/*
	 * Delete the file
	 */
	public static boolean DeleteFile(String aFile){
		if (aFile != null){
			File tFile = new File(aFile);
			
			return tFile.delete();
		}
		
		return false;
	}
	
	public static boolean DeleteTree(File aFolder){
		if (aFolder != null){
			if (aFolder.isDirectory()){
				File tFiles[] = aFolder.listFiles();
				
				if (tFiles != null && tFiles.length > 0){
					for (int i = 0; i < tFiles.length; i++){
						DeleteTree(tFiles[i]);
					}
				}
			}
			
			return aFolder.delete();
		}
		
		return false;
	}
	
	public static boolean DeleteTree(String aFolder){
		if (aFolder != null){
			return DeleteTree(new File(aFolder));
		}
		
		return false;		
	}
	
	/*
	 * Create file by byte array
	 */
	public static File CreateFile(String aFile, byte aData[], int aStartPos, int aLength, boolean aAppendMode){
		if (FileExists(aFile, true)){
			FileOutputStream tFOS = null;
			
			try {
				File tFile = new File(aFile);
				tFOS = new FileOutputStream(tFile, aAppendMode);
				
				if (tFOS != null){
					if (aStartPos == -1){
						aStartPos = 0;
					}
					if (aLength == -1){
						aLength = aData.length;
					}
					
					tFOS.write(aData, aStartPos, aLength);
				
					tFOS.close();
					
					return tFile;
				}
			} catch (IOException e1) {
				e1.printStackTrace();
				
				if (tFOS != null){
					try {
						tFOS.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
		
		return null;
	}
	
	public static File CreateFile(String aFile, String aData, boolean aAppendMode){
		PrintWriter tWriter = null;
		
		try{
			if (FileExists(aFile, true)){
				File tFile = new File(aFile);
				
				tWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(tFile, aAppendMode)));
				
				tWriter.write(aData);
				tWriter.flush();
				
				tWriter.close();
				
				return tFile;
			}
		}catch (Exception e){
			e.printStackTrace();
			
			if (tWriter != null){
				tWriter.close();
			}
		}
		
		return null;
	}
	
	public static boolean MoveFile(String aSource, String aDestination){
		if (aSource != null && aDestination != null){
			File tSrc;
			
			if ((tSrc = new File(aSource)) != null){
				String tFolder;
				
				if ((tFolder = GetFileFolder(aDestination)) != null){
					File tDest;
					
					if ((tDest = new File(tFolder)) != null){
						tDest.mkdirs();
						
						if (aDestination.endsWith("/")){
							return tSrc.renameTo(new File(tDest, tSrc.getName()));
						}else{
							return tSrc.renameTo(new File(aDestination));
						}
					}
				}
			}
		}
		
		return false;
	}
	
	/*
	 * Read file data from input stream
	 */
	public static byte[] ReadFileFromStream(InputStream aStream){
		try{
			int tLen = aStream.available();
			
			if (tLen > 0){
				byte tByte[] = new byte[tLen];
				
				aStream.read(tByte);
				
				return tByte;
			}else{
				return null;
			}
		}catch (Exception e){
			return null;
		}
	}
	
	/*
	 * Read file by path
	 */
	public static byte[] ReadFile(String aPath, boolean aRootUser){
		if (aPath != null){
			if (aRootUser == false){
				if (FileExists(aPath, false)){
					try {
						FileInputStream tStream = new FileInputStream(aPath);
						
						return ReadFileFromStream(tStream);
						
					} catch (FileNotFoundException e) {
						e.printStackTrace();
					}
				}
			}else{
				try {
					File tFile = File.createTempFile("tmp", ".su");
					
					Process tProcess = Runtime.getRuntime().exec("su ");
					OutputStream tOutput = tProcess.getOutputStream();
					
					tOutput.write(("cat " + aPath + " > " + tFile.getAbsolutePath() + "\n").getBytes());
					tOutput.flush();
					tOutput.write(("exit\n").getBytes());
					tOutput.flush();
										
					tProcess.waitFor();
					
					tProcess.destroy();
					
					if (tFile.exists()){
						byte tData[];
						
						tData = ReadFile(tFile.getAbsolutePath(), false);
						
						tFile.delete();
						
						return tData;
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}
	
	public static ArrayList<String> ReadFileLineByLine(String aPath){
		ArrayList<String> tLines = null;
		
		if (FileExists(aPath, false)){
			try{
				BufferedReader tReader = new BufferedReader(
											new InputStreamReader(
											new FileInputStream(aPath),"UTF-8"));
				if (tReader != null){
					String tLine;
					tLine = tReader.readLine();
					tLine = String.valueOf(tLine);
					
					if (tLine != null){
						tLines = new ArrayList<String>();
						
						if (tLine.length() > 0){
							if (tLine.charAt(0) == 65279){
								tLines.add(tLine.substring(1,tLine.length()));
							}else{
								tLines.add(tLine);
							}					
						}
						
						while ((tLine = tReader.readLine()) != null){
							tLines.add(tLine);
						}
					}
	
					tReader.close();
				}
			}catch (Exception e){
				e.printStackTrace();
			}
		}
		
		return tLines;
	}
	
	public static ArrayList<File> EnumFilesFromFolder(File aFolder, boolean aContainsFolder, boolean aSubFolder){
		if (aFolder != null && aFolder.exists()){
			if (aFolder.isDirectory()){
				File tFiles[] = aFolder.listFiles();
				
				if (tFiles != null && tFiles.length > 0){
					ArrayList<File> tResult = new ArrayList<File>();
					
					for (int i = 0; i < tFiles.length; i++){
						File tFile = tFiles[i];
						
						if (tFile.isDirectory()){
							if (aContainsFolder){
								tResult.add(tFile);
							}
							
							if (aSubFolder){
								ArrayList<File> tSubResult = EnumFilesFromFolder(tFile, aContainsFolder, aSubFolder);
								
								if (tSubResult != null){
									tResult.addAll(tSubResult);
								}
							}
						}else{
							tResult.add(tFile);
						}
					}
					
					if (tResult.size() > 0){
						return tResult;
					}
				}
			}
		}
		
		return null;
	}
	
	public static ArrayList<File> EnumFilesFromFolder(String aFolder, boolean aContainsFolder, boolean aSubFolder){
		if (aFolder != null){
			return EnumFilesFromFolder(new File(aFolder), aContainsFolder, aSubFolder);
		}
		
		return null;
	}
	
	public static String GetFileName(String aFile, boolean aExtension){
		if (aFile != null){
			int tStart = aFile.lastIndexOf("/");
			int tEnd = aExtension ? -1 : aFile.lastIndexOf(".");
			
			if (tStart == -1){
				if (tEnd == -1){
					return aFile;
				}else{
					return aFile.substring(0, tEnd);
				}
			}else{
				if (tEnd == -1){
					return aFile.substring(tStart + 1);
				}else{
					return aFile.substring(tStart + 1, tEnd);
				}
			}
		}
		
		return null;
	}
	
	public static String GetFileName(File aFile, boolean aExtension){
		if (aFile != null){
			return GetFileName(aFile.getName(), aExtension);
		}
		
		return null;
	}
}
